package com.alibaba.nacos.core.distributed.distro;

import com.alibaba.nacos.consistency.DataOperation;
import com.alibaba.nacos.core.cluster.Member;
import com.alibaba.nacos.core.cluster.ServerMemberManager;
import com.alibaba.nacos.core.distributed.distro.component.DistroDataProcessor;
import com.alibaba.nacos.core.distributed.distro.entity.DistroData;
import com.alibaba.nacos.core.distributed.distro.entity.DistroKey;
import com.alibaba.nacos.core.distributed.distro.task.delay.DistroDelayTask;
import com.alibaba.nacos.core.distributed.distro.task.delay.DistroDelayTaskExecuteEngine;
import io.grpc.netty.shaded.io.netty.channel.unix.DomainDatagramChannel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@RequiredArgsConstructor
public class DistroProtocol {

    @Autowired
    private ServerMemberManager memberManager;
    @Autowired
    private DistroDelayTaskExecuteEngine distroDelayTaskExecuteEngine;

    public void sync(DistroKey distroKey,
                     DataOperation dataOperation) {
        sync(distroKey, dataOperation, 1000);
    }

    private void sync(DistroKey distroKey,
                      DataOperation dataOperation,
                      long delay) {
        List<Member> members = memberManager.allMembersWithoutSelf();
        for (Member member : members) {
            synToTarget(distroKey, dataOperation, member.getAddress(), delay);
        }
    }

    private void synToTarget(DistroKey distroKey,
                             DataOperation dataOperation,
                             String targetServer,
                             long delay) {
        DistroKey distroKeyWithTarget = new DistroKey(distroKey.getResourceKey(), distroKey.getResourceType(), targetServer);
        DistroDelayTask distroDelayTask = new DistroDelayTask(distroKeyWithTarget).setDataOperation(dataOperation);
        distroDelayTask.setTaskInterval(delay);
        distroDelayTaskExecuteEngine.addTask(distroKeyWithTarget, distroDelayTask);
    }
}
